<?php
/**
 * Description of TablaResultado
 *
 * @author Milton Rubio
 *
 * @desc Clase encargada de pintar una tabla usando JQUERY
 *       con los resultados de una consulta
 */
class TablaResultado {

    protected $headers; //Dado que son los mismos titulos los del footer se usa la misma variable
    protected $tabla;
    protected $class;
    protected $link = array();
    protected $vars;
    protected $js = array();
    protected $jsVars = array();
    protected $extraLink = array();
    private   $data;
    private   $form;
    private   $thead;
    private   $tfoot;
    private   $tbody;
    private   $noFooter;
    private   $id;
    private   $tableSignature;
    private   $LinkIgnoredRowList = array();
    private   $styleClassByValue = array();
    private   $dynamicIdRow;
    private   $prefixIdRow;

    public function TablaResultado($padding=0, $spacing=0, $border=0, $id='tablaForm'){
        $this->setId($id);
        $this->tableSignature = "<div id='dt_example'>\n
                    <div id='container'>\n
                        <table cellpadding='".$padding."'  cellspacing='".$spacing."'
                        border='".$border."' class='display' id='%s'>\n";

    }//fin constructor

    public function getId(){
        return $this->id;
    }

    public function setId($id){
        $this->id = $id;
    }

    public function getDynamicIdRow(){
        return $this->dynamicIdRow;
    }

    public function setDynamicIdRow($id){
        $this->dynamicIdRow = $id;
    }

    public function getPrefixIdRow(){
        return $this->prefixIdRow;
    }

    public function setPrefixIdRow($id){
        $this->prefixIdRow = $id;
    }

    private function getIdRow($row){
        return $this->prefixIdRow.$row[$this->dynamicIdRow];
    }

    /**
     *
     *
     * Crear las cabeceras de la tabla
     */
    public function createHeaders(){

        $i = 1; //contador para titulos a no considerar

        $this->thead.= "<thead>\n<tr>\n";
        if (!is_array($this->data)) {
            foreach ($this->data as $row) {
                $keys = array_keys($row);
                break;
            }
        }
        else
            $keys = array();

        /**
         * Discriminamos los datos a mostrar
         * contra las cabeceras
         */
        foreach ($this->headers as $key => $titulo) {
            if (in_array($key, $keys)) {
                $this->thead.= "<th>" . $titulo . "</th>\n";
            } else {
                $this->thead.= "<th>" . $titulo . "</th>\n";
            }
        }
        $this->thead .= "</tr>\n</thead>\n";

    }//fin funcion
    /**
     *
     *
     * Crear el pie de la tabla
     */
    public function createFooter(){

        $this->tfoot.= "<tfoot>\n<tr>\n";
        foreach($this->headers as $titulo){
            $this->tfoot.= "<th>".$titulo."</th>\n";
        }
        $this->tfoot .= "</tr>\n</tfoot>\n";

    }
    /**
     *
     * @param array $data
     *
     * Recibe un arreglo de forma:
     *  $array[0]['campo1'] = valor
     *  $array[0]['campo2'] = valor
     *  ...
     *  $array[N]['campoN'] = valor
     */
    public function setBody(){

        $data = $this->getData();

        $this->tbody .= "<tbody>\n";
        $rowCount = 0;
        if (is_array($data)) {
            foreach ($data as $index => $row) {
                //foreach($row as $llave=>$valor){
                $idRow = $this->getIdRow($row);
                $this->tbody.= "<tr class='GradeB' id='$idRow'>\n";

                foreach ($this->headers as $llave => $titulo) {
                    //no esta en la lista negra
                    if (!$this->isRowIgnored($llave, $rowCount)) {

                        //obtenemos el estilo
                        $style = $this->getStyleField($row, $llave, $rowCount);
                        //print "<br>Estilo...$style";
                        /**
                         * Verificamos si es una liga
                         */
                        if (!empty($this->link) && array_key_exists($llave, $this->link)) {
                            $link = $this->link[$llave] . $this->getVars($row);
                            $this->tbody .= "<td class='$style'><a href='" . $link . "'>" . $row[$llave] . "</a></td>\n";
                        }
                        /**
                         * Verificamos si es un JS
                         */ else if (!empty($this->js) && array_key_exists($llave, $this->js)) {
                            $js = "javascript:" . $this->js[$llave] . "(" . $this->getJSVars($llave, $row) . ");";
                            $this->tbody .= "<td class='$style'><a href='#' onclick='" . $js . "' >" . $row[$llave] . "</a></td>\n";
                        } else {
                            if (array_key_exists($llave, $row)) {
                                $this->tbody .= "<td class='$style'>" . $row[$llave] . "</td>\n";
                            } else if (!empty($this->extraLink) && array_key_exists($llave, $this->extraLink)) {
                                $this->formExtraLink($this->extraLink[$llave]);
                                $jsLlaves = array_keys($this->extraLink[$llave]);
                                $js = "javascript:" . $this->js[$jsLlaves[0]] . "(" . $this->getJSVars($jsLlaves[0], $row) . ");";
                                $this->tbody .= "<td class='$style'><a href='#' onclick='" . $js . "' >" . $jsLlaves[0] . "</a></td>\n";
                            }
                            else
                                $this->tbody .= "<td class='$style'>" . $this->extraLink[$llave] . "</td>\n";
                        }
                    }else {
                        $this->tbody .= "<td class='$style'>&nbsp;</td>";
                    }
                }
                $this->tbody .= "</tr>\n";
                //}
                $rowCount++;
            }
        }
        $this->tbody .= "</tbody>\n";

    }

    //aqui se podria manejar estilo non o par con rowCount
    public function getStyleField($row, $llave, $rowCount){

        $x = $this->styleClassByValue[$llave][$row[$llave]];
        return $x;
    }

    public function setLinkIgnoredRowList($list){
        $this->LinkIgnoredRowList = $list;

    }

    public function isRowIgnored($link, $row){

        if($this->LinkIgnoredRowList[$link][$row]=="x"){
            $retValue = true;
        }else{
            $retValue = false;
        }

        return $retValue;
    }
    public function createTable(){
        $this->renderSignature();
        $this->tabla .= $this->form;
        $this->createHeaders();
        $this->tabla .= $this->getHead();
        $this->tabla .= $this->getBody();
        $this->createFooter();

        if($this->noFooter)
            $this->tabla .= $this->getFoot();

        $this->tabla .= $this->closeTable();
    }

    private function renderSignature(){
        $this->form = sprintf($this->tableSignature, $this->id);
    }
    public function getBody(){
        return $this->tbody;
    }
    public function getForm(){
        return $this->form;
    }
    public function getHead(){
        return $this->thead;
    }
    public function getFoot(){
        return $this->tfoot;
    }

    /**
     * Construye y despliega la tabla
     */
    public function displayTable(){
        $this->createTable();
        echo $this->tabla;
    }
    public function setHeaders($headers, $foot=false){
        $this->headers  = $headers;
        $this->noFooter = $foot;
    }

    public function getHeaders(){
        return $this->headers;
    }

    public function setFooter($foot){
        $this->headers = $foot;
    }

    public function getFooter(){
        return $this->headers;
    }

    /**
     *
     * @param array $link
     * Recibe como parametro un arreglo $arr['campo']=valor
     */
    public function setLink($link, $vars=null){
        $this->link = $link;

        if(is_array($vars)){
            $this->vars=$vars;
        }
    }

    public function setStyleClassByValues($styleClassByValue){
        $this->styleClassByValue= $styleClassByValue;
    }



    public function getLink(){
        return $this->link;
    }

    public function formVars($vars, $row){
        foreach ($vars as $campo=>$variable){
            $varsVals .= "&".$variable."=". $row[$campo];
        }
        return $varsVals;
    }

    public function getVars($row){
        return $this->formVars($this->vars,$row);
    }

    /**
     *
     * @param array $js
     * @param bool  $merge Si se anexa otro arreglo al arreglo $js
     *
     * Recibe como parametro un arreglo $arr['campo']= valor
     */
    public function setJS($js, $merge=false){
        $comillas = array("\"","'");
        
        foreach ($js as $llave => $valor){
            $arrT = explode('@', $valor);
            $tmp[$llave]     = str_replace($comillas, "\"",$arrT[0]);
            $arrVars[$llave] = explode(',', $arrT[1]);
        }

        if(!$merge)
            $this->js = $tmp;
        else{
            $tt = array_merge ($this->js, $tmp);
            $this->js = $tt;
        }
        if(!$merge)
            $this->jsVars = $arrVars;
        else{
            $tt = array_merge ($this->jsVars, $arrVars);
            $this->jsVars = $tt;
        }
    }

    public function setData($data){
        $this->data = $data;
    }

    public function getData(){
        return $this->data ;
    }

    public function getJS(){
        return $this->js;
    }

    public function setExtraLink($extraLink){
        $this->extraLink = $extraLink;
    }

    public function getExtraLink(){
        return $this->extraLink;
    }

    private function getJSVars($llave, $data){
        $llavesData = array_keys($data);

        foreach ($this->jsVars[$llave] as $valor){
            if($valor == 'this')
                $vars[] = "this";
            else if(!in_array(trim($valor), $llavesData)){
                $vars[] = "\"".trim($valor)."\"";
            }
            else
                $vars[] = "\"".$data[trim($valor)]."\"";
        }
        return implode(',', $vars);

    }
    /**
     * Funcion encargada de formar una funcion JS sobre el texto que se indique
     * en el arreglo.
     *
     * @param array $link Arreglo de la forma $arr['index']['texto'] = "function@param1,param2,..."
     */
    public function formExtraLink($link){
        foreach($link as $liga)
            if(strpos($liga, '@'))
                $this->setJS($link, true);
            else {
                $this->setLink($link);
            }


    }
    public function closeTable(){
        return '</table></div></div>';
    }

    public function addToJSCollection(){
        return "<script> </script>";
    }
}
?>
